﻿using MiniFox.Components;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace MiniFox
{
    /// <summary>
    /// 
    /// </summary>
    public static class MiniFoxApplication
    {
        static bool hasInitialized;
        static CancellationTokenSource cancellationTokenSource;
        /// <summary>
        /// 
        /// </summary>
        static MiniFoxApplication()
        {
            hasInitialized = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        public static void Run(params string[] args)
        {
            if (hasInitialized)
                return;

            if (cancellationTokenSource != null)
            {
                Stop();
            }
            List<Task> tasks = new List<Task>();
            List<CancellationToken> tokens = new List<CancellationToken>();
            foreach (Type type in ComponentFactory.AppStartTypes)
            {
                var appStart = Activator.CreateInstance(type) as IApplicationRunner;
                tokens.Add(appStart.CancellationToken);
                Task task = Task.Run(() => appStart.OnProcess(args), appStart.CancellationToken);
                tasks.Add(task);
            }
            cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(tokens.ToArray());
            hasInitialized = true;
            Task.WaitAll(tasks.ToArray());
        }
        /// <summary>
        /// 
        /// </summary>
        public static void Stop()
        {
            if (cancellationTokenSource != null)
            {
                cancellationTokenSource.Cancel();
                cancellationTokenSource.Dispose();
            }
            hasInitialized = false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static async Task RunAsync(params string[] args)
        {
            if (hasInitialized)
                return;

            List<Task> tasks = new List<Task>();
            List<CancellationToken> tokens = new List<CancellationToken>();
            foreach (Type type in ComponentFactory.AppStartTypes)
            {
                var appStart = Activator.CreateInstance(type) as IApplicationRunner;
                tokens.Add(appStart.CancellationToken);
                var task = appStart.OnProcessAsync(args);
                tasks.Add(task);
            }
            cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(tokens.ToArray());
            hasInitialized = true;
            foreach (Task task in tasks) {
                await task;
            }
        }
    }
}
